﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using Utility.Inspector;

namespace Utility.Serializable
{
	[CustomPropertyDrawer (typeof (NullableFloat))]
	public class NullableFloatDrawer : PropertyDrawer
	{
		SerializedProperty p_hasValue, p_value;
		string name;
		bool cache = false;

		public override void OnGUI (Rect position, SerializedProperty property, GUIContent label)
		{
			if (!cache)
			{
				name = property.displayName;
				p_hasValue = property.FindPropertyRelative ("hasValue");
				p_value = property.FindPropertyRelative ("value");
				cache = true;
			}

			EditorGUI.BeginProperty (position, label, property);
			{
				EditorGUI.BeginChangeCheck ();
				float? value = p_hasValue.boolValue ? p_value.floatValue : default (float?);
				value = EditorGUIEX.NullableFloatField (position, label, value);
				if (EditorGUI.EndChangeCheck ())
				{
					p_hasValue.boolValue = value.HasValue;
					p_value.floatValue = value.HasValue ? value.Value : default;
				}
			}
			EditorGUI.EndProperty ();
		}

		public override float GetPropertyHeight (SerializedProperty property, GUIContent label)
		{
			return EditorGUIUtility.singleLineHeight;
		}
	}

	[CustomPropertyDrawer (typeof (NullableInt))]
	public class NullableIntDrawer : PropertyDrawer
	{
		SerializedProperty p_hasValue, p_value;
		string name;
		bool cache = false;

		public override void OnGUI (Rect position, SerializedProperty property, GUIContent label)
		{
			if (!cache)
			{
				name = property.displayName;
				p_hasValue = property.FindPropertyRelative ("hasValue");
				p_value = property.FindPropertyRelative ("value");
				cache = true;
			}

			EditorGUI.BeginProperty (position, label, property);
			{
				EditorGUI.BeginChangeCheck ();
				int? value = p_hasValue.boolValue ? p_value.intValue : default (int?);
				value = EditorGUIEX.NullableIntField (position, label, value);
				if (EditorGUI.EndChangeCheck ())
				{
					p_hasValue.boolValue = value.HasValue;
					p_value.intValue = value.HasValue ? value.Value : default;
				}
			}
			EditorGUI.EndProperty ();
		}

		public override float GetPropertyHeight (SerializedProperty property, GUIContent label)
		{
			return EditorGUIUtility.singleLineHeight;
		}
	}

	[CustomPropertyDrawer (typeof (NullableBool))]
	public class NullableBoolDrawer : PropertyDrawer
	{
		SerializedProperty p_hasValue, p_value;
		string name;
		bool cache = false;

		public override void OnGUI (Rect position, SerializedProperty property, GUIContent label)
		{
			if (!cache)
			{
				name = property.displayName;
				p_hasValue = property.FindPropertyRelative ("hasValue");
				p_value = property.FindPropertyRelative ("value");
				cache = true;
			}

			EditorGUI.BeginProperty (position, label, property);
			{
				EditorGUI.BeginChangeCheck ();
				bool? value = p_hasValue.boolValue ? p_value.boolValue : default (bool?);
				value = EditorGUIEX.NullableBoolField (position, label, value);
				if (EditorGUI.EndChangeCheck ())
				{
					p_hasValue.boolValue = value.HasValue;
					p_value.boolValue = value.HasValue ? value.Value : default;
				}
			}
			EditorGUI.EndProperty ();
		}

		public override float GetPropertyHeight (SerializedProperty property, GUIContent label)
		{
			return EditorGUIUtility.singleLineHeight;
		}
	}
}